#include <pthread.h>
#include <semaphore.h>

#define MAX_NUM		10

unsigned char card_num = 1;

#define IS_MULTI_CARD(number)   (number > 1)

static int global_id = 0;


typedef struct _nlist_node_t {
	struct _nlist_node_t* pre;
	struct _nlist_node_t* next;
}nlist_node_t;


typedef struct _nlist_t {
	nlist_node_t* first;
	nlist_node_t* last;
	sem_t semaphore;
    pthread_mutex_t mutex;
}nlist_t;

typedef struct _card_t {
	nlist_node_t node;
	int id;
	int fd;
}card_t;


void nlist_node_init(nlist_node_t* node) {
	node->pre = node->next = (nlist_node_t*)0;
}

void nlist_init(nlist_t* list) {
	list->first = (nlist_node_t*)0;
	list->last = (nlist_node_t*)0;
	sem_init(&list->semaphore, 0, 0);
    pthread_mutex_init(&list->mutex, NULL);
}

void nlist_free(nlist_t* list) {
	list->first = (nlist_node_t*)0;
	list->last = (nlist_node_t*)0;
	sem_destroy(&list->semaphore);
    pthread_mutex_destroy(&list->mutex);
}

void nlist_insert(nlist_t* list, nlist_node_t* node) {
	pthread_mutex_lock(&list->mutex);
	node->next = (nlist_node_t*)0;
	node->pre = list->last;

	nlist_node_t* last = list->last;
	if (last == (nlist_node_t*)0) {
		list->first = node;
		list->last = node;
	}
	else {
		last->next = node;
		list->last = node;
	}
	pthread_mutex_unlock(&list->mutex);

    sem_post(&list->semaphore);
}

nlist_node_t* nlist_remove(nlist_t* list) {
	sem_wait(&list->semaphore);

    pthread_mutex_lock(&list->mutex);

	nlist_node_t* node = list->first;

	if (node->next) {
		node->next->pre = node->pre;
	}
	if (node->pre) {
		node->pre->next = node->next;
	}
	if (node == list->last)
		list->last = node->pre;

	list->first = node->next;

	node->pre = node->next = (nlist_node_t*)0;

	pthread_mutex_unlock(&list->mutex);

	return node;
}

void card_init(card_t* card, int fd) {
	nlist_node_init(&card->node);
	card->id = global_id++;
	card->fd = fd;
}
